﻿using System;
using System.Collections.Generic;
using System.Linq;
using Pap.Data;
using Pap.Services;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class CustomerHistoryViewModel : IViewModel
    {
        /// <summary>
        /// 
        /// </summary>
        ILoanRepository loanRepository;
        /// <summary>
        /// 
        /// </summary>
        IAdministrationRepository adminRepository;
        /// <summary>
        /// 
        /// </summary>
        ILookUpRepository lookupRepository;
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService _WfService;

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomerHistoryViewModel"/> class.
        /// </summary>
        /// <param name="loanRepository">The loan repository.</param>
        /// <param name="adminRepo">The admin repo.</param>
        /// <param name="lookupRepo">The lookup repo.</param>
        /// <param name="wfService">The wf service.</param>
        public CustomerHistoryViewModel(ILoanRepository loanRepository, IAdministrationRepository adminRepo, ILookUpRepository lookupRepo, IWorkflowService wfService)
        {
            this.loanRepository = loanRepository;
            this.adminRepository = adminRepo;
            this.lookupRepository = lookupRepo;
            _WfService = wfService;
        }

        /// <summary>
        /// Gets the customer by ID.
        /// </summary>
        /// <param name="customerID">The customer ID.</param>
        /// <returns></returns>
        public ICustomer GetCustomerByID(string customerID)
        {
            Guid custGuid = new Guid(customerID);
            return loanRepository.GetCustomerByID(custGuid);
        }

        /// <summary>
        /// Gets the customer loan history by ID.
        /// </summary>
        /// <param name="strCustomerID">The STR customer ID.</param>
        /// <returns></returns>
        public CustomerLoanDisplay[] GetCustomerLoanHistoryByID(string strCustomerID)
        {
            Guid customerID = new Guid(strCustomerID);
            var allLoans = loanRepository.GetAllCustomerLoans(customerID);

            List<CustomerLoanDisplay> displayLoans = new List<CustomerLoanDisplay>();
            foreach (var loan in allLoans)
            {
#warning Only closed loans are displayed here. The open loan data will not be shown in the history.
                ICustomerLoanHistory history = loanRepository.FindCustomerHistories(h => h.LoanID == loan.LoanID).FirstOrDefault();
                if (history == null)
                    continue;

                CustomerLoanDisplay ln = new CustomerLoanDisplay()
                {
                    CommitteeIDLoanNumber = loan.CommitteeID.ToString() + "/" + loan.LoanNumber.ToString(),
                    LoanID = history.LoanID,
                    LoanNumber = loan.LoanNumber,
                    LoanCreatedDate = loan.LoanCreatedDate,
                    ProjectName = (adminRepository.GetProjectStageByID(loan.ProjectStageID)).ProjectObj.ProjectName,
                    ProjectStage = loanRepository.GetProjectStageName(loan.ProjectStageID),
                    OldCustomerCode = history.OldCustomerCode ?? String.Empty,
                    LastConsecutiveDelay = history.LastConsecutiveDelay ?? 0,
                    LastDiscreteDelay = history.LastDiscreteDelay ?? 0,
                    //TODO: Correct the guarantor calculation
                    //Guarantor75Percent = true,

                    PreviousTrials = lookupRepository.GetPreviousTrialsCloseType().Select(lookup => lookup.ID).Contains(
                    history.LoanHistoryCloseTypeID.Value)
                };

                displayLoans.Add(ln);
            }

            return displayLoans.ToArray();
        }

        /// <summary>
        /// Gets the name of the customer loan history by.
        /// </summary>
        /// <param name="strCustomerName">Name of the STR customer.</param>
        /// <returns></returns>
        public CustomerLoanDisplay[] GetCustomerLoanHistoryByName(string strCustomerName)
        {
            List<CustomerLoanDisplay> displayLoans = new List<CustomerLoanDisplay>();
            var histories = loanRepository.FindCustomerHistories(h => h.CustomerName == strCustomerName);
            foreach (var history in histories)
            {

                CustomerLoanDisplay ln = new CustomerLoanDisplay()
                {
                    CommitteeIDLoanNumber = "",
                    LoanID = history.LoanID,
                    LoanNumber = 0,
                    LoanCreatedDate = (DateTime)history.LoanExecutionDate,
                    ProjectName = (history.LoanProjectStageID == null) ? "" : (adminRepository.GetProjectStageByID((Guid)history.LoanProjectStageID)).ProjectObj.ProjectName,
                    ProjectStage = (history.LoanProjectStageID == null) ? -1 : loanRepository.GetProjectStageName((Guid)history.LoanProjectStageID),
                    OldCustomerCode = history.OldCustomerCode,
                    LastConsecutiveDelay = history.LastConsecutiveDelay ?? 0,
                    LastDiscreteDelay = history.LastDiscreteDelay ?? 0,
                    //TODO: Correct the guarantor calculation
                    //Guarantor75Percent = true,
                    PreviousTrials = lookupRepository.GetPreviousTrialsCloseType().Select(lookup => lookup.ID).Contains(
                    history.LoanHistoryCloseTypeID.Value)
                };

                displayLoans.Add(ln);
            }

            return displayLoans.ToArray();
        }

        /// <summary>
        /// Gets the loan notes.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <returns></returns>
        public string GetLoanNotes(Guid loanID)
        {
            return _WfService.GetStep(_WfService.GetProcessInstanceIDByEntity(loanID)).PreviousNotes;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class CustomerLoanDisplay
    {
        /// <summary>
        /// Gets or sets the committee ID loan number.
        /// </summary>
        /// <value>
        /// The committee ID loan number.
        /// </value>
        public string CommitteeIDLoanNumber { get; set; }
        /// <summary>
        /// Gets or sets the loan ID.
        /// </summary>
        /// <value>
        /// The loan ID.
        /// </value>
        public Guid? LoanID { get; set; }
        /// <summary>
        /// Gets or sets the loan number.
        /// </summary>
        /// <value>
        /// The loan number.
        /// </value>
        public int LoanNumber { get; set; }
        /// <summary>
        /// Gets or sets the loan created date.
        /// </summary>
        /// <value>
        /// The loan created date.
        /// </value>
        public DateTime LoanCreatedDate { get; set; }
        /// <summary>
        /// Gets or sets the name of the project.
        /// </summary>
        /// <value>
        /// The name of the project.
        /// </value>
        public string ProjectName { get; set; }
        /// <summary>
        /// Gets or sets the project stage.
        /// </summary>
        /// <value>
        /// The project stage.
        /// </value>
        public int ProjectStage { get; set; }
        /// <summary>
        /// Gets or sets the old customer code.
        /// </summary>
        /// <value>
        /// The old customer code.
        /// </value>
        public string OldCustomerCode { get; set; }
        /// <summary>
        /// Gets or sets the last consecutive delay.
        /// </summary>
        /// <value>
        /// The last consecutive delay.
        /// </value>
        public int LastConsecutiveDelay { get; set; }
        /// <summary>
        /// Gets or sets the last discrete delay.
        /// </summary>
        /// <value>
        /// The last discrete delay.
        /// </value>
        public int LastDiscreteDelay { get; set; }
        //public bool Guarantor75Percent { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether [previous trials].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [previous trials]; otherwise, <c>false</c>.
        /// </value>
        public bool PreviousTrials { get; set; }
    }
}
